#ifndef __INCSessionh
#define __INCSessionh
#include <string>
#include <mutex>
#include <type.h>
#include <reSocket.h>
#include <declarecClass.h>
#include <UserInfo.h>

constexpr unsigned int SESSION_LOGIN_TIMEOUT = 30;
constexpr unsigned int SESSION_ALIVE_TIMEOUT = 300;

class Session 
{
private:
    DISABLE_COPY_CLASS(Session);
    SocketHandle m_socket;
    struct sockaddr_in m_address;
    std::string m_readBuffer;
    std::string m_writeBuffer;
    mutable std::mutex m_readLock;
    mutable std::mutex m_writeLock;
    bool m_isClosed;

    AuthStage m_authStage;
    std::string m_username;
    UserPermission m_permission;
    std::string m_prompt;
    int m_heartbeatTimeout;
    int m_loginRetryCount;

public:
    Session(SocketHandle sock, const struct sockaddr_in& addr);
    ~Session();

    AuthStage getAuthStage() const;
    void setAuthStage(AuthStage stage);
    bool isAuthenticated() const;
    void setUsername(const std::string &username);
    const std::string &getUsername() const;
    const UserPermission &getPermission() const;
    void setPermission(UserPermission permission);
    void resetHeartbeatTimer(int timeSec);
    bool checkHeartbeatValidity() const;
    void refreshHeartbeatTimer();
    void refreshAuthFail();

    SocketHandle getSocket() const;
    const struct sockaddr_in& getAddress() const;
    std::string getAddressStr() const;
    const std::string getUsrPrompt() const;
    void extractRowData(std::string& cmdStr);
    void appendReadData(const char* data, size_t len);
    void appendReadData(const std::string& data);
    void appendWriteData(const char* data, size_t len);
    void appendWriteData(const std::string& data);
    void clearReadBuffer();
    void clearWriteBuffer();
    bool isClosed() const;
    bool isWritable() const;
    bool isReadable() const;
    void close();
    ssize_t recv();
    ssize_t send();
};
using SessionPtr = Session*;
#endif // __INCSessionh